
#ifndef __RSP_CONTROLLER__HEADER_FILE__
#define __RSP_CONTROLLER__HEADER_FILE__


#include "rsp_def.h"
#include "coid/comm/hptimer.h"


////////////////////////////////////////////////////////////////////////////////
extern MsecTimer    _Timer;

#define MSEC_TO_TICKS(ms)           ((1000*ms)/_Timer.get_period_usec())

////////////////////////////////////////////////////////////////////////////////
struct timefmt
{
    timefmt() : _msec(_Timer.time()) {}
    timefmt( uint fr, bool isframenum=true )
    {
        _msec = isframenum
            ? uint( ((uint64)fr*_Timer.get_period_usec())/1000 )
            : fr;
    }

    friend binstream& operator << ( binstream& bin, const timefmt& t )
    {
        static charstr _str;

        _str.reset();
        _str.append_num( 10, t._msec/1000/60/60, 2, charstr::ALIGN_NUM_FILL_WITH_ZEROS );
        _str.append(':');
        _str.append_num( 10, (t._msec/1000/60)%60, 2, charstr::ALIGN_NUM_FILL_WITH_ZEROS );
        _str.append(':');
        _str.append_num( 10, (t._msec/1000)%60, 2, charstr::ALIGN_NUM_FILL_WITH_ZEROS );
        _str.append('.');
        _str.append_num( 10, t._msec%1000, 3, charstr::ALIGN_NUM_FILL_WITH_ZEROS );

        bin << _str;
        return bin;
    }

    uint _msec;
};


////////////////////////////////////////////////////////////////////////////////
struct rsp_controller
{
    uint get_current_stateid() const        { return _stateid; }
    //const uint* get_current_stateid_ptr() const { return &_stateid; }

    bool client_side() const                { return _ctrltype == CT_CLIENT; }

    virtual rsp_base* owned_instance( const token& clsname )    { return 0; }


    virtual ~rsp_controller() {}
    explicit rsp_controller( int ctrltype ) : _ctrltype(ctrltype)
    {
        _stateid = UMAX;
        current = this;
    }


    ///Return current controller, client or server
    static rsp_controller* current;
    static uint get_frame_usec()            { return _Timer.get_period_usec(); }

protected:

    uint _stateid;                          ///< current state id
    int  _ctrltype;

    ///controller type
    enum {
        CT_CLIENT               = -1,
        CT_SERVER               = 1,
    };
};


#endif //__RSP_CONTROLLER__HEADER_FILE__
